/**
	License:		Artistic license 2.0 (see license.txt, also available online at http://www.perlfoundation.org/artistic_license_2_0)
	Authors:		OrbitalLab (http://www.orbitallab.ru/moonglide/), 2007-2009

	File:			EngCamera.d
	Description:	camera basic class
	Date:			20.11.2007 by Digited
*/
module moonglide.core.engobjects.EngCamera;

import moonglide.core.engobjects.EngObject;

//================================================================
/// basic camera class
//================================================================
class CEngCamera : public CEngObject
{
    protected:
        float   _fov,
                _near,
                _far;
        bool    _persp, _changed = true;

        Size2ui _viewp;

        void ConstructMatrix()
        {
            if( _persp )
				projection = Matrix44f.perspective( _fov, cast(float)_viewp.x / cast(float)_viewp.y, _near, _far );
			else
				projection = Matrix44f.ortho( 0.0, cast(float)_viewp.x, cast(float)_viewp.y, 0.0 );
        }
	public:
		Matrix44f	projection;		/// must be generated from moonmath.linalgebra.Matrix44.perspective or ortho

		Vector3f v1,v2,v3,v4;

        Size2ui    viewport()
        {
            return _viewp;
        }
        void    viewport(Size2ui s)
        {
//            if(_viewp == s)
//                return;
            _viewp = s;
            _changed = true;
            ConstructMatrix();
        }

        bool    changed()
        {
            bool a = _changed;
            _changed = false;
            return a;
        }
        bool    perspective()
        {
            return _persp;
        }
        void    perspective(bool per)
        {
//            if(_persp == per)
//                return;
            _persp = per;
            _changed = true;
            ConstructMatrix();
        }

        float   fov()
        {
            return _fov;
        }
        void   fov(float f)
        {
//            if(_fov == f)
//                return;
            _fov = f;
            _changed = true;
            ConstructMatrix();
        }


        float   far()
        {
            return _far;
        }
        void   far(float f)
        {
 //           if(_far == f)
 //               return;
            _far = f;
            _changed = true;
            ConstructMatrix();
        }


        float   near()
        {
            return _near;
        }
        void   near(float f)
        {
//            if(_near == f)
//                return;
            _near = f;
            _changed = true;
            ConstructMatrix();
        }

		this(
			Size2ui screensize,
			char[] idname = "EngCamera",
			bool perspective = true,
			float fov = 45.0,
			float near = 0.5,
			float far = 10000.0 )
		{
			super( idname );

            _viewp = screensize;
            _persp = perspective;
            _far = far;
            _near = near;
            _fov = fov;

            _changed = true;

			ConstructMatrix();
		}

		bool isInFrustum( inout CEngObject obj )
		{
			obj.disToCam = (obj.wposition - wposition).norm;
			// boundCheck
			return true;
		}

		override void update( float timeelapsed, ref Vector3f parentWPos, ref Matrix33f parentWOrient )
		{
			super.update( timeelapsed, parentWPos, parentWOrient );

			static Vector3f VR,VU;

			VR.set(worientation[0]);
			VU.set(worientation[1]);

			v1.set( -VR.x-VU.x  , -VR.y-VU.y  , -VR.z-VU.z );
			v2.set(  VR.x-VU.x  ,  VR.y-VU.y  ,  VR.z-VU.z );
			v3.set(  VR.x+VU.x  ,  VR.y+VU.y  ,  VR.z+VU.z );
			v4.set( -VR.x+VU.x  , -VR.y+VU.y  , -VR.z+VU.z );

			///debug debugLogB("uPDATE CAmera" ~ id ~ " x: "~floatToStr(v1.x)~ " y: "~floatToStr(v1.y));
		}


}
